package ferp.core.state;

import ferp.core.game.Game;
import ferp.core.game.Input;
import ferp.core.game.Settings;
import ferp.core.log.Log;
import ferp.core.mode.Mode;
import ferp.core.player.Profile;

import java.io.IOException;
import java.util.HashMap;

/**
 * User: igorgok
 * Date: 10/22/11 9:34 PM
 */
public abstract class State
{
  // process result
  public static final class Result
  {
    public static final int SHOW_OPTIONS = 0;
    public static final int SCHEDULE     = 1;
  }

  public static State get(String name) {return states.get(name);}

  public State() {states.put(getClass().getName(), this);}

  // processing entry point - calls current state's process method
  public int execute(Game.Listener listener, Profile profile, Game g, Settings settings, Input input) throws Game.Error
  {
    Mode mode = g.mode();

    int r = process(listener, profile, g, settings, input);

    if (r == Result.SHOW_OPTIONS)
      mode.show(listener, g, settings);

    return r;
  }

  // next state
  public State next() {return null;}
  public void next(State state) {/* empty by default */}

  protected abstract int process(Game.Listener listener, Profile profile, Game g, Settings settings, Input input) throws Game.Error;

  // save the current state
  protected void save(Profile profile)
  {
    try
    {
      Log.debug(Log.TAG, "saving the game; state=" + (profile.game() == null ? "null" : profile.game().state) + ", mode=" + (profile.game() == null ? "null" : profile.game().mode));

      profile.save();
    }
    catch (IOException e)
    {
      Log.error(Log.TAG, e);
    }
  }

  // states hash map
  private static final HashMap<String, State> states = new HashMap<String, State>();

  // predefined states
  public static final Resume resume = new Resume();
  public static final State replay = new Replay();

  public static final State fastMoving = new FastMoving();
  public static final State ttc = new TrickingTenCheck();

  public static final State introduction = new Introduction();

  public static final State initialize = new Initialize();
  public static final State gio = new GetInputOptions();
  public static final State am = new ActorMoving();
  public static final State process = new Process();
  public static final State chill = new Chill();
  public static final State summarize = new Summarize();
  public static final State score = new Score();
  public static final State showPool1 = new ShowPool1();
  public static final State showPool2 = new ShowPool2();
  public static final State showInitialPosition = new ShowInitialPosition();
  public static final State end = new End();
}
